package com.authsphere.security.account.api.lock;

import com.authsphere.common.annotation.NamedField;
import com.authsphere.common.entity.PluginData;
import com.authsphere.common.enums.PluginBeforeEnum;
import com.authsphere.plugin.api.AuthSphereBeforePluginChain;
import com.authsphere.plugin.api.WebExchange;
import com.authsphere.plugin.base.AbstractAuthSphereBeforePlugin;
import com.authsphere.plugin.base.cache.AnnotationDataCache;
import com.authsphere.plugin.base.entity.AnnotationFieldBean;
import com.authsphere.plugin.base.utils.AnnotationProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.LockedException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @program: AuthSphere
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/25 11:54
 **/
public class AccountLockBeforePlugin extends AbstractAuthSphereBeforePlugin {
    private static final Logger log = LoggerFactory.getLogger(AccountLockBeforePlugin.class);
    private final AccountLockoutService accountLockoutService;

    public AccountLockBeforePlugin(AccountLockoutService accountLockoutService) {
        this.accountLockoutService = accountLockoutService;
    }

    @Override
    protected void doExecute(WebExchange exchange, AuthSphereBeforePluginChain chain, PluginData pluginData) {
        AnnotationFieldBean<NamedField> annotationData = AnnotationDataCache.getAnnotationData(exchange.getRequestBody().getClass(), NamedField.class);
        if (annotationData == null) {
            chain.execute(exchange);
            return;
        }
        String name = "";
        try {
            name = (String) annotationData.getGetterMethod().invoke(exchange.getRequestBody());
        } catch (Exception e) {
            log.error("{} doExecute method invoke exception, reason:", name(), e);
            chain.execute(exchange);
            return;
        }
        int lockedTime = accountLockoutService.getLockedTime(name);
        if (lockedTime > 0) {
            boolean locked = accountLockoutService.isLocked(name);
            if (!locked) {
                chain.execute(exchange);
            } else {
                // 账号被锁定
                throw new LockedException(String.format("您的账号已锁定，请等待[%s]分钟后重试", lockedTime));
            }

        } else if (lockedTime < 0) {
            // 账号永久锁定
            throw new LockedException("您的账号已被永久锁定，请联系管理员");
        }
        chain.execute(exchange);
    }

    @Override
    public int getOrder() {
        return PluginBeforeEnum.ACCOUNT_LOCK.getCode();
    }

    @Override
    public String name() {
        return PluginBeforeEnum.ACCOUNT_LOCK.getName();
    }
}
